home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 007 / jclib.cq / jclib.c
Text File  |  1985-06-14  |  16KB  |  780 lines

  1. /* These C functions are for use with the Lattice C Compiler, version
  2.    2.14, and are supplied for your use by Dr. Jim Conn of Micro Solutions 
  3.    Associates, Route 1 Swallowfield, Frankfort, KY  40601 */
  4.  
  5. #include "stdio.h"
  6. #include "dos.h"
  7. downstr(b)
  8. /*convert string to lower case*/
  9. char *b;
  10. {
  11.     while(*b != '\0') {
  12.         *b = tolower(*b);
  13.         b++;
  14.     }
  15. }
  16. getl(fi, s)
  17. /*get a line of data from file fi, terminated by a newline, into array s */
  18. /*does not include the newline*/
  19. char s[];
  20. FILE *fi;
  21. {
  22.     int c, i;
  23.     i = 0;
  24.     while ((c = fgetc(fi)) != -1 && (c & 127) != '\n') {
  25.         c = c & 127;
  26.         s[i++] = c;
  27.     }
  28.     s[i] = '\0';
  29.     return(i);
  30. }
  31. ltoasc(n, s)
  32. /* convert LONG n to a string pointed to by s */
  33. char *s;
  34. long n;
  35. {
  36.     int i;
  37.     long sign;
  38.     if ((sign = n) < 0L)
  39.         n = -n;
  40.     i = 0;
  41.     do {
  42.         s[i++] = n % 10L + '0';
  43.     } while ((n /= 10L) > 0L);
  44.     if (sign < 0L)
  45.         s[i++] = '-';
  46.     s[i] = '\0';
  47.     reverse(s);
  48. }
  49. upstr(b)
  50. /*convert string b to uppercase */
  51. char *b;
  52. {
  53.     while(*b != '\0') {
  54.         *b = toupper(*b);
  55.         b++;
  56.     }
  57. }
  58. hash(s, hashsize)
  59. /*return hashvalue of string in s, bounded by hashsize */
  60. char *s;
  61. int hashsize;
  62. {
  63.     int hashval;
  64.     for (hashval = 0; *s != '\0';)
  65.         hashval += *s++;
  66.     return(hashval % hashsize);
  67. }
  68. reverse(s)
  69. /* reverse string s */
  70. char s[];
  71. {
  72.     int c, i, j;
  73.     for (i = 0, j = strlen(s)-1; i < j; i++, j--) {
  74.         c = s[i];
  75.         s[i] = s[j];
  76.         s[j] = c;
  77.     }
  78. }
  79. instr(s, t)
  80. /* return index of t in s, -1 if none */
  81. char s[], t[];
  82. {
  83.     int i, j, k;
  84.     for (i = 0; s[i] != '\0'; i++) {
  85.         for (j=i, k=0; t[k] != '\0' && s[j] == t[k]; j++, k++)
  86.             ;
  87.         if (t[k] == '\0')
  88.             return(++i);
  89.         }
  90.         return(-1);
  91. }
  92. midstr(x, i, j, buf)
  93. int i, j;
  94. char *x, *buf;
  95. {
  96. /*this function returns a string of length j characters
  97. from string x beginning with character number i.
  98. if length of x is less than i, returns null string.
  99. if length of x from i pos. is less than j characters, 
  100. returns all characters to the right of i position.
  101. similar to MID$(X$, I, J) in MBASIC. */
  102.  
  103.     int l;
  104.     if(i < 1)
  105.         i = 1;
  106.     if((strlen(x)) < i) {
  107.         buf[0] = '\0';
  108.         return(0);
  109.     }
  110.     x = x+i-1;
  111.     if((strlen(x)) < j) {
  112.         strcpy(buf, x);
  113.         return(0);
  114.     }
  115.     for(l = 0; l < j; l++)
  116.         buf[l] = x[l];
  117.     buf[l] = '\0';
  118. }
  119. leftstr(x, i, buf)
  120. int i;
  121. char *x, *buf;
  122. {
  123.  
  124. /*this function returns a string of length j characters
  125. from the left side of string x.
  126. if i = 0, returns null string.
  127. if i is greater than the length of x, returns x.
  128. similar to LEFT$(X$, I) in MBASIC. */
  129.  
  130.     int l;
  131.     if(i == 0) {
  132.         buf[0] = '\0';
  133.         return(0);
  134.     }
  135.     if(i > (strlen(x))) {
  136.         strcpy(buf, x);
  137.         return(0);
  138.     }
  139.     for(l = 0; l < i; l++)
  140.         buf[l] = x[l];
  141.     buf[l] = '\0';
  142. }
  143. rightstr(x, i, buf)
  144. int i;
  145. char *x, *buf;
  146. {
  147.  
  148. /*this function returns a string of length i characters
  149. from the right side of string x.
  150. if i = 0, returns null string.
  151. if i is greater than the length of x, returns x.
  152. similar to  RIGHT$(X$, I) in MBASIC. */
  153.  
  154.     if(i == 0) {
  155.         buf[0] = '\0';
  156.         return(0);
  157.     }
  158.     if(i > (strlen(x))) {
  159.         strcpy(buf, x);
  160.         return(0);
  161.     }
  162.     x += ((strlen(x)) - i);
  163.     strcpy(buf, x);
  164.     return(0);
  165. }
  166. getline(fi, s, lim)
  167. /* get a line of chars from file fi into s, with maximum of lim chars */
  168. /* if lim is not reached, will return a newline at the end */
  169. char s[];
  170. int lim;
  171. unsigned fi;
  172. {
  173.     int c, i;
  174.     i = 0;
  175.     while (--lim > 0 && (c = fgetc(fi)) != -1 && (c & 127) != '\n') {
  176.         c = c & 127;
  177.         s[i++] = c;
  178.     }
  179.     if ((c & 127) == '\n')
  180.         s[i++] = c & 127;
  181.     s[i] = '\0';
  182.     return(i);
  183. }
  184. char *strsave(s)
  185. /* saves string s, and returns a pointer to the location */
  186. char *s;
  187. {
  188.     char *p, *malloc();
  189.     if ((p = malloc(strlen(s)+1)) != 0)
  190.         strcpy(p,s);
  191.     return(p);
  192. }
  193. getn(fi, w)
  194. /* get the next ascii number string from file fi, and return it in w */
  195. char *w;
  196. unsigned fi;
  197. {
  198.     int c, t;
  199.     c = fgetc(fi);
  200.     while(c != EOF && (isdigit(c) == 0))
  201.         c = fgetc(fi);
  202.     if(c == EOF)
  203.         return(EOF);
  204.     while(c != EOF)
  205.         {
  206.         c &= 127;
  207.         if(isdigit(c))
  208.             *w++ = c;
  209.         else
  210.             {
  211.             *w = '\0';
  212.             return(1);
  213.             }
  214.         c = fgetc(fi);
  215.         }
  216.     return(EOF);
  217. }
  218. getbits(x, p, n)
  219. /* this function is handy for extracting the value of a range of bit
  220. positions in a number, and finds good use when doing system calls
  221. where certain bit positions have value. It returns an int value of
  222. the bits.  NOTE: get n bits from x, beginning at position p, as per
  223. K & R book, p. 45; but the thing is, it gets them from the position p
  224. DOWN! So, to get bits 5, 6 & 7 from number x, specify as follows:
  225. valbits = getbits(x, 7, 3);  See what I mean? 
  226. */
  227. int x, p, n;
  228. {
  229.     return((x >> (p+1-n)) & ~(~0 << n));
  230. }
  231. getpgrf(fi, s)
  232. /* This function returns a paragraph of text from file fi, in string s.
  233. A paragraph is defined as a string of text terminated by a doublespace.
  234. (Two newlines). */
  235. char *s;
  236. unsigned fi;
  237. {
  238.     int d, c, i;
  239.     i = 0;
  240.     while ((c = fgetc(fi)) != EOF) 
  241.         {
  242.         s[i++] = (c & 127);
  243.         if((d = fgetc(fi)) != EOF)
  244.             if((c == '\n') && ((d & 127) == '\n'))
  245.                 break;
  246.         else
  247.             ungetc(d, fi);
  248.         }
  249.     s[i] = '\0';
  250.     if(c == EOF || d == EOF)
  251.         return(EOF);
  252.     else
  253.         return(i);
  254. }
  255. frame(row, col, hgt, wdth)
  256. /* frame makes a window frame on the crt. */
  257. int row, col, hgt, wdth;
  258.  
  259. {
  260.     int x, y;
  261.     
  262.  
  263.     cls(); 
  264.     putcur(row, col); 
  265.     putchar(201);
  266.     for(x = col + 1; x <=(col + wdth -1); x++)
  267.          putchar(205);
  268.         putchar(187);
  269.         for(x = row + 1; x <=(row + hgt - 1); x++){
  270.         putcur(x, col);    
  271.         putchar(186);
  272.         putcur(x, col+wdth);
  273.         putchar(186);
  274.    }
  275.     putcur(x, col);  
  276.     putchar(200);
  277.     for(x= col + 1; x <=(col + wdth -1); x++)
  278.         putchar(205);
  279.         putchar(188);    
  280. }
  281. logo(program, name)
  282. /* makes an attractive display of program and author's name on
  283. the CRT.  */
  284. char *program, *name;
  285. {
  286.     int i, c, z;
  287.     char *string(), a1[3], a2[3];
  288.     a1[0] = 'B';
  289.     a1[1] = '\0';
  290.     a2[0] = 'Y';
  291.     a2[1] = '\0';
  292.     beep();
  293.     cls();
  294.     c = 10;
  295.     disp(c, a1, a2, program, name);
  296.     program = string(' ',(strlen(program)));
  297.     a1[0] = ' ';
  298.     a2[0] = ' ';
  299.     name = string(' ',(strlen(name)));
  300.     c= 9;
  301.     disp(c, a1, a2, program, name);
  302.     for(z=1; z < 30000; z++)
  303.         ;
  304. }
  305. disp(c, a1, a2, a, a3)
  306. /* function disp is required for the logo function */
  307. int c;
  308. char *a1, *a2, *a, *a3;
  309. {
  310.     int i, j, jj;
  311.     for(i=1; i <= c; i++)
  312.         {
  313.         j = strlen(a);
  314.         j /= 2;
  315.         j = 40-j;
  316.         putsa(a, 0x07, i, j);
  317.         j = 4*i;
  318.         putsa(a1, 0x07, 12, j);
  319.         j = 81-(4*i);
  320.         putsa(a2, 0x07, 12, j);
  321.         j = 24-i;
  322.         jj = 41 - ((strlen(a3))/2);
  323.         putsa(a3, 0x07, j, jj);
  324.         }
  325. }
  326. writeca(c, a, cnt)
  327. /* writes char c with attribute a cnt times beginning at current cursor position */
  328. char c, a;
  329. int cnt;
  330. {
  331. /*
  332. Some attribute values:
  333. REVERSE VIDEO & BLNK    = 0xf0;
  334. REVERSE VIDEO        = 0X70;
  335. NORMAL BUT WITH BLNK     = 0X87;
  336. NORMAL WITH NOBLNK     = 0x07;
  337. */
  338.     union REGS inr;
  339.     union REGS outr;
  340.     struct SREGS segr;
  341.     segread(&segr);
  342.     inr.h.bh = 0;
  343.     inr.h.bl = a;
  344.     inr.h.al = c;
  345.     inr.x.cx = cnt;
  346.     inr.h.ah = 9;
  347.     int86x(0x10, &inr, &outr, &segr);
  348. }
  349. scrlwnd(brow,bcol,erow,ecol,atr,num)
  350. /* scroll a window down. */
  351. char brow,bcol,erow,ecol,atr,num;
  352. {
  353.     union REGS inr;
  354.     union REGS outr;
  355.     struct SREGS segr;
  356.     segread(&segr);
  357.     inr.h.ch = brow;
  358.     inr.h.cl = bcol;
  359.     inr.h.dh = erow;
  360.     inr.h.dl = ecol;
  361.     inr.h.bh = atr;
  362.     inr.h.al = num;
  363.     inr.h.ah = 7;
  364.     int86x(0x10, &inr, &outr, &segr);
  365. }
  366. scrlwnu(brow,bcol,erow,ecol,atr,num)
  367. /* scroll a window up. */
  368. char brow,bcol,erow,ecol,atr,num;
  369. {
  370.     union REGS inr;
  371.     union REGS outr;
  372.     struct SREGS segr;
  373.     segread(&segr);
  374.     inr.h.ch = brow;
  375.     inr.h.cl = bcol;
  376.     inr.h.dh = erow;
  377.     inr.h.dl = ecol;
  378.     inr.h.bh = atr;
  379.     inr.h.al = num;
  380.     inr.h.ah = 6;
  381.     int86x(0x10, &inr, &outr, &segr);
  382. }
  383. curtype(bgn, end)
  384. /* set the cursor type. beg=0,end=12 for block, beg=11,end=12 for normal */
  385. char bgn, end;
  386. {
  387.     union REGS inr;
  388.     union REGS outr;
  389.     struct SREGS segr;
  390.     segread(&segr);
  391.     inr.h.ch = bgn;
  392.     inr.h.cl = end;
  393.     inr.h.ah = 1;
  394.     int86x(0x10, &inr, &outr, &segr);
  395. }
  396. setmode(mode)
  397. /* set the video mode. Returns 1 if not equipped; EOF if bad mode; 0 if ok */
  398. char mode;
  399. {
  400. /*     0 = 40x25 b&w 
  401.     1 = 40x25 color
  402.      2 = 80x25 b&w
  403.     3 = 80x25 color
  404.     4 = 320x200 color
  405.     5 = 320x200 b&w
  406.     6 = 640x200 b&w
  407. */
  408.     int equip;
  409.     union REGS inr;
  410.     union REGS outr;
  411.     struct SREGS segr;
  412.     segread(&segr);
  413. /* return EOF if invalid mode */
  414.     if(mode > 6)
  415.         return(EOF);
  416.     /* now get equipment to see if color or mono */
  417.     int86x(0x11, &inr, &outr, &segr);
  418.     equip = getbits(outr.x.ax, 5, 2);
  419. /* returns:     1 = 40x25 color card
  420.         2 = 80x25 color card
  421.         3 = monochrome */
  422.     if(equip < 3)
  423.         {
  424.         inr.h.al = mode;
  425.         inr.h.ah = 0;
  426.         int86x(0x10, &inr, &outr, &segr);
  427.         return(0);
  428.         }
  429.     else
  430.         return(1); /* not equipped */
  431. }
  432. statins()
  433. /* see if INS is on */
  434. {
  435.     union REGS inr;
  436.     union REGS outr;
  437.     struct SREGS segr;
  438.     segread(&segr);
  439.     inr.h.ah = 2;
  440.     int86x(0x16, &inr, &outr, &segr);
  441.     return(getbits(outr.h.al, 7, 1));    /* Insert on */
  442. }    
  443. statcaps()
  444. /* SEE IF CAPS LOK IS ON */
  445. {
  446.     union REGS inr;
  447.     union REGS outr;
  448.     struct SREGS segr;
  449.     segread(&segr);
  450.     inr.h.ah = 2;
  451.     int86x(0x16, &inr, &outr, &segr);
  452.     return(getbits(outr.h.al, 6, 1));    /* caps lok on */
  453. }
  454. statnum()
  455. /* SEE IF NUM LOK IS ON */
  456. {
  457.     union REGS inr;
  458.     union REGS outr;
  459.     struct SREGS segr;
  460.     segread(&segr);
  461.     inr.h.ah = 2;
  462.     int86x(0x16, &inr, &outr, &segr);
  463.     return(getbits(outr.h.al, 5, 1));    /* num lok on */
  464. }
  465. statscrl()
  466. /* SEE IF SCROLL LOK IS ON */
  467. {
  468.     union REGS inr;
  469.     union REGS outr;
  470.     struct SREGS segr;
  471.     segread(&segr);
  472.     inr.h.ah = 2;
  473.     int86x(0x16, &inr, &outr, &segr);
  474.     return(getbits(outr.h.al, 4, 1));    /* scroll lok on */
  475. }
  476. statshalt()
  477. /* SEE IF SHIFT/ALT IS PRESSED */
  478. {
  479.     union REGS inr;
  480.     union REGS outr;
  481.     struct SREGS segr;
  482.     segread(&segr);
  483.     inr.h.ah = 2;
  484.     int86x(0x16, &inr, &outr, &segr);
  485.     return(getbits(outr.h.al, 3, 1));    /* shift/alt pressed */
  486. }
  487. statshcrl()
  488. /* SEE IF SHIFT/CTRL IS PRESSED */
  489. {
  490.     union REGS inr;
  491.     union REGS outr;
  492.     struct SREGS segr;
  493.     segread(&segr);
  494.     inr.h.ah = 2;
  495.     int86x(0x16, &inr, &outr, &segr);
  496.     return(getbits(outr.h.al, 2, 1));    /* shift/ctrl pressed */
  497. }
  498. statlshf()
  499. /* SEE IF LEFT-SHIFT KEY IS PRESSED */
  500. {
  501.     union REGS inr;
  502.     union REGS outr;
  503.     struct SREGS segr;
  504.     segread(&segr);
  505.     inr.h.ah = 2;
  506.     int86x(0x16, &inr, &outr, &segr);
  507.     return(getbits(outr.h.al, 1, 1));    /* left shift pressed */
  508. }
  509. statrshf()
  510. /* SEE IF RIGHT-SHIFT KEY IS PRESSED */
  511. {
  512.     union REGS inr;
  513.     union REGS outr;
  514.     struct SREGS segr;
  515.     segread(&segr);
  516.     inr.h.ah = 2;
  517.     int86x(0x16, &inr, &outr, &segr);
  518.     return(getbits(outr.h.al, 0, 1));    /* right shift pressed */
  519. }
  520. writech(c, cnt)
  521. /* write char c cnt times beginning at current cursor position */
  522. char c;
  523. int cnt;
  524. {
  525.     union REGS inr;
  526.     union REGS outr;
  527.     struct SREGS segr;
  528.     segread(&segr);
  529.     inr.h.bh = 0;
  530.     inr.h.al = c;
  531.     inr.x.cx = cnt;
  532.     inr.h.ah = 10;
  533.     int86x(0x10, &inr, &outr, &segr);
  534. }
  535. char *string(c, len)
  536. /* returns a pointer to a string of character c, len long */
  537. char c;
  538. int len;
  539. {
  540.     int i;
  541.     char *s_tr, *malloc();
  542.     s_tr = malloc(len+1);
  543.     for(i=0; i < len; i++)
  544.         s_tr[i] = c;
  545.     s_tr[i] = '\0';
  546.     return(s_tr);
  547. }
  548. double getdbl()
  549. /* returns a double input as an ascii string at current cursor position */
  550. {
  551.     double atof(), val;
  552.     char *s, *malloc();
  553.     int rowcol, row, col, dot, i, j, len;
  554.     s = malloc(50);
  555.     getcur(&row, &col);
  556. ngd:    gets(s);
  557.     len = strlen(s);
  558.     for(i = 0; i < len; i++)
  559.         if((s[i] < 48 && s[i] != 46) || s[i] > 57)
  560.             {
  561.             putcur(row, col);
  562.             writech(' ', len);
  563.             putcur(row, col);
  564.             goto ngd;
  565.         }
  566.     val = atof(s);
  567.     return(val);
  568. }
  569. long getlong()
  570. /* returns a long input as an ascii string at current cursor positon */
  571. {
  572.     long atol(), val;
  573.     char *s, *malloc();
  574.     int rowcol, row, col, dot, i, j, len;
  575.     s = malloc(50);
  576.     getcur(&row, &col);
  577. ngd:    gets(s);
  578.     if((len = strlen(s)) > 10)
  579.             {
  580.             putcur(row, col);
  581.             writech(' ', len);
  582.             putcur(row, col);
  583.             goto ngd;
  584.             }
  585.     if(len == 10 && s[0] > 1)
  586.             {
  587.             putcur(row, col);
  588.             writech(' ', len);
  589.             putcur(row, col);
  590.             goto ngd;
  591.             }
  592.     for(i = 0; i < len; i++)
  593.         if(s[i] < 48 || s[i] > 57)
  594.             {
  595.             putcur(row, col);
  596.             writech(' ', len);
  597.             putcur(row, col);
  598.             goto ngd;
  599.         }
  600.     val = atol(s);
  601.     return(val);
  602. }
  603. getint()
  604. /* returns an int input as an ascii string at current cursor position */
  605. {
  606.     int atoi(), val;
  607.     char *s, *malloc();
  608.     int rowcol, row, col, dot, i, j, len;
  609.     s = malloc(50);
  610.     getcur(&row, &col);
  611. ngd:    gets(s);
  612.     len = strlen(s);
  613.     for(i = 0; i < len; i++)
  614.         if(s[i] < 48 || s[i] > 57)
  615.             {
  616.             putcur(row, col);
  617.             writech(' ', len);
  618.             putcur(row, col);
  619.             goto ngd;
  620.         }
  621.     val = atoi(s);
  622.     return(val);
  623. }
  624. getcur(row, col)
  625. /*  Return current cursor position.
  626. USAGE:  getcur(&row, &col); with row and col as ints */
  627. int *row, *col;
  628. {
  629.     union REGS inr;
  630.     union REGS outr;
  631.     struct SREGS segr;
  632.     segread(&segr);
  633.     inr.h.bh = 0;
  634.     inr.h.ah = 3;
  635.     int86x(0x10, &inr, &outr, &segr);
  636.     *row = outr.h.dh;
  637.     *col = outr.h.dl;
  638. }
  639. putcur(row, col)
  640. /* put the cursor to col, row */
  641. char row, col;
  642. {
  643.     union REGS inr;
  644.     union REGS outr;
  645.     struct SREGS segr;
  646.     segread(&segr);
  647.     inr.h.bh = 0;    /* page zero */
  648.     inr.h.dh = row;
  649.     inr.h.dl = col;
  650.     inr.h.ah = 2;
  651.     int86x(0x10, &inr, &outr, &segr);
  652. }
  653. getkb()
  654. /* gets a keyboard character, with scan code in bits 7-4, character in 
  655. bits 3-0. use getbits to extract from return value. */
  656. {
  657.     int c;
  658.     union REGS inr;
  659.     union REGS outr;
  660.     struct SREGS segr;
  661.     segread(&segr);
  662.     inr.h.ah = 0;
  663.     int86x(0x16, &inr, &outr, &segr);
  664.     c = outr.x.ax;
  665.     return(c);
  666. }
  667. getfk()
  668. /* gets an extended key code (function or alt-key character). */
  669. {
  670.     int c;
  671.     union REGS inr;
  672.     union REGS outr;
  673.     struct SREGS segr;
  674.     segread(&segr);
  675.     inr.h.ah = 0;
  676.     int86x(0x16, &inr, &outr, &segr);
  677.     c = outr.h.ah;
  678.     return(c);
  679. }
  680. putcom(port, c)
  681. /* puts a character to com1 or Com2.  port for
  682.    Com1 = 1, Com2 = 2 */
  683. char c;
  684. int port;
  685. {
  686.     long q;
  687.     union REGS inr;
  688.     union REGS outr;
  689.     struct SREGS segr;
  690.     segread(&segr);
  691.     if(port == 2)
  692.         port = 1;
  693.     else
  694.         port = 0;
  695.     inr.h.ah = 1;
  696.     inr.h.al = c;
  697.     inr.x.dx = port;
  698.     int86x(0x14, &inr, &outr, &segr);
  699. }
  700. initcom(port)
  701. /* initializes Hayes Smartmodem */
  702. char port;
  703. {
  704.         long q;
  705.         if(port == 2)
  706.             port = 1;
  707.         else
  708.             port = 0;
  709.         putcom(port, 'A');
  710.         putcom(port, 'T');
  711.         putcom(port, 'Z');
  712.         putcom(port, 13);
  713.         for(q=0L; q<50000L; q++);
  714. }
  715. hangup(port)
  716. /* hangs up the comport 'port'. 1 = Com1:, 2 = Com2: */
  717. char port;
  718. {
  719.         if(port == 2)
  720.             port = 1;
  721.         else
  722.             port = 0;
  723.         putcom(port, 'A');
  724.         putcom(port, 'T');
  725.         putcom(port, 'H');
  726.         putcom(port, 13);
  727. }
  728. dial(port, num)
  729. /* dials the number string in num via Hayes Smartmodem attached to port. 1=Com1:
  730. 2=Com2:
  731. char *num;
  732. {
  733.     long q;
  734.     int i, len;
  735.     if(port == 2)
  736.         port = 1;
  737.     else
  738.         port = 0;
  739.     len = strlen(num);
  740.     for(q=0L; q < 10000L; q++);
  741.     putcom(port, 'A');
  742.     putcom(port, 'T');
  743.     putcom(port, 'D');
  744.     putcom(port, 'T');
  745.     for(i = 0; i < len; i++)
  746.         putcom(port, num[i]);
  747.     putcom(port, 13);
  748. }
  749. putsa(s, a, row, col)
  750. /* put string s to console with attribute a beginning at row, col */
  751. char *s, a;
  752. int row, col;
  753. {
  754.     int i;
  755.     for(i = 0; s[i] != '\0'; i++)
  756.         {
  757.         putcur(row, col++);
  758.         writeca(s[i], a, 1);
  759.         }
  760. }
  761. getca(c, row, col)
  762. /* Read character and attribute at cursor position. */
  763. /* Usage:  attr = getca(&c, row, col); */
  764. char *c;
  765. int row, col;
  766. {
  767.     int attr;
  768.     union REGS inr;
  769.     union REGS outr;
  770.     struct SREGS segr;
  771.     segread(&segr);
  772.     putcur(row, col);
  773.     inr.h.ah = 8;
  774.     inr.h.bh = 0;
  775.     int86x(0x10, &inr, &outr, &segr);
  776.     *c = outr.h.al;
  777.     attr = outr.h.ah;
  778.     return(attr);
  779. }
  780.